package com.joysuch.wwyt.streampusher.publisher;

import com.joysuch.wwyt.streampusher.exception.PushException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;

/**
 * JavaCVRtmp推流器
 * 关闭流会出bug，不要用了
 * @author qingzhou
 *         2017-11-07 17:56
 */
@Deprecated
public class JavaCVRtmpStreamPusher implements StreamPusher {

    private static final Logger logger = LoggerFactory.getLogger(JavaCVRtmpStreamPusher.class);

    /*static {
        Loader.load(opencv_objdetect.class);
    }*/

    /**
     * 是否关闭
     */
    private volatile boolean closed;
    /**
     * 视频流捕捉器
     */
//    private FrameGrabber grabber;
    /**
     * 推流器
     */
//    private FrameRecorder recorder;
    /**
     * 流的标识，同一个原始流，应该使用同一个标识
     * 避免反复创建同一个流提高性能
     */
    private String identify;
    /**
     * 输入源
     */
    private String input;
    /**
     * 输出
     */
    private String output;
    /**
     * 视频宽度
     */
    private int imgWidth;
    /**
     * 视频高度
     */
    private int imgHeight;
    /**
     * 帧率
     */
    private int frameRate;
    /**
     * 执行取流操作的线程池
     */
    private ScheduledThreadPoolExecutor executor;

    public JavaCVRtmpStreamPusher(final String identify, String input, String output, int imgWidth, int imgHeight, int frameRate) {
        this.closed = true;
        this.identify = identify;
        this.input = input;
        this.output = output;
        this.imgWidth = imgWidth;
        this.imgHeight = imgHeight;
        this.frameRate = frameRate;
        this.executor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread newT = new Thread(r);
                newT.setName("publisher-" + identify);
                return newT;
            }
        });
    }

    @Override
    public String identify() {
        return this.identify;
    }

    @Override
    public boolean isClosed() {
        return closed;
    }

    @Override
    public void close() throws PushException {
        /*closed = true;
        logger.error(identify + "-" + input + " to " + output + " closing without exception ");
        closePublisher();
        logger.info("wait shutdown sleeping...");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.executor.shutdown();*/
    }

    @Override
    public void open() throws PushException {
        /*try {
            grabber = TcpTolerateAudioFailFFmpegFrameGrabber.createDefault(this.input);
            grabber.setImageWidth(imgWidth);
            grabber.setImageHeight(imgHeight);
            grabber.setFrameRate(frameRate);
            grabber.setAudioChannels(0);
            grabber.start();
        } catch (FrameGrabber.Exception e) {
            try {
                grabber.restart();
            } catch (FrameGrabber.Exception e1) {
                throw new PushException(identify + " start grabber failed.", e);
            }
        }
        try {
            recorder = FrameRecorder.createDefault(this.output, this.imgWidth, this.imgHeight);
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("flv");
            recorder.setFrameRate(this.frameRate);
            recorder.setGopSize(this.frameRate);
            recorder.setAudioChannels(0);
            recorder.start();
        } catch (FrameRecorder.Exception e) {
            throw new PushException(identify + " start recorder failed.", e);
        }
        closed = false;
        logger.info(identify + " started...");
        addNextGrabTask();*/
    }

    /*private void addNextGrabTask() {
        this.executor.schedule(new Runnable() {
            @Override
            public void run() {
                if (!closed) {
                    try {
                        Frame frame = grabber.grab();
                        recorder.setTimestamp(System.nanoTime() / 1000);
                        if (frame != null) {
                            recorder.record(frame);
                        }
                    } catch (FrameGrabber.Exception e) {
                        logger.error(identify + "-" + input + " to " + output + " FrameGrabber.Exception:", e);
                        closePublisher();
                    } catch (FrameRecorder.Exception e) {
                        logger.error(identify + "-" + input + " to " + output + " FrameRecorder.Exception:", e);
                        closePublisher();
                    }
                    addNextGrabTask();
                }
            }

        }, 1000000 / this.frameRate, TimeUnit.NANOSECONDS);
    }

    private void closePublisher() {
        try {
            logger.info(identify + " stopping grabber...");
            if (grabber != null) {
                grabber.stop();
            }
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        }
        try {
            logger.info(identify + " stopping recorder...");
            if (recorder != null) {
                recorder.close();
            }
        } catch (FrameRecorder.Exception e) {
            e.printStackTrace();
        }
    }*/
}
